package com.ytzl.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.crypto.SecureUtil;
import com.ytzl.common.Constants;
import com.ytzl.common.UserAgentUtil;
import com.ytzl.config.RedisAPI;
import com.ytzl.modul.ItripUser;
import com.ytzl.service.TokenService;
import cz.mallat.uasparser.UserAgentInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * token实现类
 */
@Slf4j
@Service
public class TokenServiceImpl implements TokenService {
    //token前缀
    public final String TOKEN_PREFIX="token";
    @Resource
    private RedisAPI redisAPI;
    //token有效期
    private Long expire= Constants.SESSION_EXPIRE;

    @Override
    public String createToken(String agent, ItripUser user) {
        //自定义token的数据格式：前缀+设备类型+userCode+userId+时间戳+6位随机数
        StringBuilder token=new StringBuilder();
        token.append(TOKEN_PREFIX).append(":");
        try {
            //1.获取客户端设备类型
            UserAgentInfo parse=UserAgentUtil.getUasParser().parse(agent);
            String deviceType=parse.getDeviceType();
            if (deviceType.equals(UserAgentInfo.UNKNOWN)){//检测是否是移动端设备
                if (UserAgentUtil.CheckAgent(agent)){
                    token.append("MoBILE");
                }else {
                    token.append("PC");
                }
            }else if (deviceType.equals("Personal computer")){
                token.append("PC");
            }else {
                token.append("MoBILE");
            }
            log.info(deviceType);
            //2.获取token需要的其他信息
            //加密的userCode
            String userCodeMd5= SecureUtil.md5(user.getUsercode());
            token.append("-").append(userCodeMd5);
            //用户id
            Long userId=user.getId();
            token.append("-").append(userId);
            //当前时间，时间戳
            String time=new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
            token.append("-").append(time);
            //随机随机数
            String uuid=UUID.randomUUID().toString().replace("-","");
            String random=uuid.substring(0,6);
            token.append("-").append(random);
            //3.返回token
            return token.toString();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }



    }

    @Override
    public void saveToken(String token, ItripUser user) {
        //如果客户端是pc，则设置token的过期时间
        if (token.startsWith(TOKEN_PREFIX+"PC-")){
            redisAPI.set(token,user,expire);
        }else {
            //如果客户端是移动设备，则不设置token的过期时间
            redisAPI.set(token,user);
        }
    }

    @Override
    public boolean validateToken(String agent, String token) {
        //没有token，返回false
        if (redisAPI.hasKey(token)){
            return false;
        }
        //如果有token，需要验证token是否在有效期内
        //token:PC-b7782e510d27f86dd1ba7c0c915c2351-12-20210929101845-0e9bb9
        String[] chars=token.split("-");
        //从token中获取token创建的时间
        String charForTime=chars[3];
        try {
            //转换时间格式
            Date date=new SimpleDateFormat("yyMMddhhmmss").parse(charForTime);
            //当前时间
            long nowTime= Calendar.getInstance().getTimeInMillis();
            long tokenCreateTime=date.getTime();
            long betweenTime=nowTime-tokenCreateTime;
            //用当前时间减去创建token的时间
            //如果区间值是大于系统设置token过期时间
            //则表示，该token过期
            if (betweenTime>Constants.SESSION_EXPIRE){
                return false;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return false;
    }
}
